#!/usr/bin/env bash
# init

. "${DIR}/exec/_aac.sh"  || exit 1;
[[ "${OSTP}" != "deb" ]] && f_fail 'init: not debian10';
[[ `cat '/etc/debian_version'` != "10."* ]] && f_fail 'init: not debian10';

######## prepare
. "${DIR}/.env.sh" || f_fail 'init: load .env.sh';
f_mode "${DIR}/.env.sh" '-' 700 'root:root';
rm -rf "${DEL}" || f_fail 'init: del old DEL';
mkdir -p "${DEL}" || f_fail 'init: mkdir DEL';
mkdir -p "${TMP}" || f_fail 'init: mkdir TMP';
mkdir -p "${MEM}" || f_fail 'init: mkdir MEM';
if [[ -f "${MEM}/upgrade" ]]; then f_info 'init: upgrade already';
else
    f_wait 'init: apt upgrade';
    apt update || f_fail 'init: apt update';
    apt upgrade -y || f_fail 'init: apt upgrade';
    echo > "${MEM}/upgrade" || f_fail 'init: upgrade status';
fi;

######## 网络下载
f_down(){ # type, name, url, [isXz:1]
    local n=$2;  [[ -n "$4" ]] && n="$2.xz";  local o="${TMP}/${2}";
    [[ ! -f "${o}.down" ]] && [[ -f "${o}" ]] && return;
    cd "${TMP}" || f_fail "$1: down cd to TMP, ${n}";
    echo > "${o}.down" || f_fail "$1: down save status, ${n}";
    wget -c "$3" -O "${n}" || f_fail "$1: down wget, ${n}";
    if [[ -n "$4" ]]; then xz -d "${n}" || f_fail "$1: down xz -d, ${n}"; fi;
    rm -f "${o}.down" || f_fail "$1: down del status, ${n}";
}

######## apt安装
f_inst(){ # type, list
    local lst='';  local ins="${MEM}/instsall";
    if [[ ! -f "${ins}" ]]; then lst="$2";
    else
        local tmp=$(cat "${ins}");  local n;  local has;
        for n in $2; do
            has=$(echo "${tmp}" | grep -F " ${n} ");
            [[ -z "${has}" ]] && lst="${lst} ${n}";
        done;
    fi;
    [[ -z "${lst}" ]] && return;
    apt -y install ${lst} || f_fail "$1: ins.apt: ${lst}";
    echo " ${lst} " >> "${ins}" || f_fail "$1: ins.mem: ${lst}";
}
f_wait 'init: apt install';  f_inst 'init' "apt-transport-https ${c_init_ins}";

######## 开机执行
f_wait 'init: auto start';
run="${EXE}/auto.sh";  add="\n${run} e;\n";  rc='/etc/rc.local';
[[ -n "${c_init_home}" ]] && add="mount -U ${c_init_home} /home;${add}";
[[ ! -f "${rc}" ]] && echo -e '#!/usr/bin/env bash\n' > "${rc}";
f_bkup "${rc}" 1;  f_copy "${rc}.backup" "${rc}" 755 '-' 'root:root';
echo -e "\n${add}" >> "${rc}" || f_fail 'init: auto rc.local';
echo '#!/usr/bin/env bash
if [[ "$(id -u)" != "0" ]]; then sudo -sE "$0" "${1}" || exit 1; exit; fi;
log="/var/log/auto.log";  [[ ! -f "${log}" ]] && echo -n > "${log}";
if [[ "${1}" = "p" ]]; then cat "${log}"; exit; fi;
if [[ "${1}" = "c" ]]; then echo -n > "${log}"; exit; fi;
if [[ "${1}" != "e" ]]; then echo "  usage: auto.sh p|c|e,  p=print c=clean e=exec"; exit 1; fi;
echo "### $(date +"%F %T")" >> "${log}";
systemctl daemon-reload 2>>"${log}";
' > "${run}" || f_fail 'init: auto init file';
f_mode "${run}" '755' '-' 'root:root';
f_auto(){ # typ, src, [isSrv:1]
    local src="$2";  local run="${EXE}/auto.sh";  
    if [[ "$3" = "1" ]]; then
        systemctl disable "$2" &>/dev/null || f_fail "$1: auto srv disable";
        src="systemctl start $2";
    fi;
    src="${src} 2>>\"\${log}\";";
    [[ -n `cat "${run}" | grep -F "${src}"` ]] && return;
    echo "${src}" >> "${run}" || f_fail "$1: auto add";
}

######## bashrc
f_wait 'init: global bashrc';
rc='/etc/bash.bashrc';  f_bkup "${rc}" 1; f_copy "${rc}.backup" "${rc}" 755;
echo -e "\n\n. ${DIR}/conf/bash.sh;\n" >> "${rc}" ||  f_fail 'init: bashrc';

######## users
lst="root www git ${c_init_user}";  run='/bin/bash';
f_wait "init: users, ${lst}";
rc='#!/usr/bin/env bash\n[[ -f /etc/bashrc ]] && . /etc/bashrc;\n';
pro='#!/usr/bin/env bash\n[[ -e ~/.bashrc ]] && . ~/.bashrc;\n';
for u in ${lst}; do
    d="/home/${u}";  m="init: user ${u},";  own="${u}:${u}";
    if [[ -n "$(id "${u}" -u 2>/dev/null)" ]]; then
        if [[ "${u}" = "root" ]]; then d='/root';
        else
            usermod -d "${d}" -s "${run}" "${u}" \
                &>/dev/null || f_fail "${m} usermod";
        fi;
    else
        rm -rf "/var/spool/mail/${u}" || f_fail "${m} del mail";
        if [[ -d "${d}" ]]; then
            useradd "${u}" -UM -s "${run}" || f_fail "${m}, create";
            f_mode "${d}" '-' '-' "${u}:${u}";
        else
            useradd "${u}" -Um -s "${run}" || f_fail "${m}, create";
        fi;
    fi;
    # bashrc
    if [[ ! -e "${d}/.bashrc" ]]; then
        rm -rf "${dir}/.bashrc" || f_fail "${m} del .bashrc";
        echo "${rc}" > "${d}/.bashrc" || f_fail "${m} .bashrc";
        f_mode "${d}/.bashrc" '755' '-' "${own}";
    fi;
    # bash_profile
    if [[ ! -e "${d}/.bash_profile" ]]; then
        rm -rf "${d}/.bash_profile" || f_fail "${m} del .bash_profile";
        echo "${pro}" > "${d}/.bash_profile" || f_fail "${m} .bash_profile";
        f_mode "${d}/.bash_profile" '755' '-' "${own}";
    fi;
    # ssh
    mkdir -p "${d}/.ssh" || f_fail "${m} mkdir .ssh";
    f_mode "${d}/.ssh" '700' '-' "${own}";
    # git
    src="${DIR}/conf/git/config";  tar="${d}/.gitconfig";
    [[ ! -f "${tar}" ]] && f_link "${src}" "${tar}" "${own}";
done;

######## hosts
f_bkup '/etc/hosts' '1';  cfg="${DIR}/conf/.hosts";
[[ ! -f "${cfg}" ]] && f_copy '/etc/hosts.backup' "${cfg}";
f_link "${cfg}" '/etc/hosts';

######## swap
m='close'; [[ -n "${c_init_swap}" ]] && m="open 1024*${c_init_swap}";
m="init: swap ${m}";  tar="${MEM}/swapfile";
mem="${MEM}/swap.tmp";  mnt=`swapon -s | grep -F "${tar}"`;
has=$(cat "${mem}" 2>/dev/null);
f_wait "${m}";
if [[ -z "${c_init_swap}" ]] || [[ "${has}" != "${c_init_swap}" ]]; then
    if [[ -n "${mnt}" ]]; then
        swapoff "${tar}" || f_fail "${m}, ummount";
        mnt='';
    fi;
    if [[ -f "${tar}" ]]; then
        rm -f "${tar}" || f_fail "${m}, rm file";
    fi;
    echo > "${mem}" || f_fail "${m}, close status";
fi;
if [[ -n "${c_init_swap}" ]]; then
    # f_wait "${m}";
    if [[ "${has}" != "${c_init_swap}" ]]; then
        dd if=/dev/zero of="${tar}" bs=1024 count=${c_init_swap} || f_fail "${m}, create file";
        mkswap "${tar}" || f_fail "${m}, make file";
        chmod 600 "${tar}" || f_fail "${m}, chmod file";
        echo "${c_init_swap}" > "${mem}" || f_fail "${m}, save status";
    fi;
    if [[ -z "${mnt}" ]]; then swapon "${tar}" || f_fail "${m}, mount"; fi;
    f_auto 'init.swap' "swapon '${tar}'";
fi;

######## firewalld
f_wait 'init: firewalld install'; # start
f_inst 'init' 'firewalld';
cfg='/etc/firewalld/firewalld.conf';
txt=$(cat "${cfg}");  tar="IndividualCalls=yes";
old=$(echo -e "${txt}" | grep -E '^IndividualCalls=');
run=$(ps -ef | grep -F 'firewalld' | grep -v 'grep');
if [[ "${old}" != "${tar}" ]]; then
    txt=${txt/${old}/${tar}};  f_bkup "${cfg}";
    echo -e "${txt}" > "${cfg}" || f_fail 'init: firewalld config';
    if [[ -n "${run}" ]]; then
        systemctl restart firewalld || f_fail 'init: firewalld restart';
    fi;
fi;
systemctl enable firewalld &>/dev/null || f_fail 'init: firewalld enable';
if [[ -z "${run}" ]]; then
    systemctl start firewalld || f_fail 'init: firewalld start';
fi;
f_wait "init: firewalld open, ${c_init_firewalld}"; # port
exe="firewall-cmd --zone=public";
has=$(${exe} --list-ports) || f_fail 'init: firewalled ports';
exe="${exe} --permanent";  has=" ${has} ";  reload='';
for v in ${c_init_firewalld}; do
    if [[ "${has}" = *" ${v} "* ]]; then has=${has/ ${v} / };
    else
        reload='1';
        x=$(${exe} --add-port=${v}) || f_fail "init: firewalld add ${v}";
        f_info "init: firewalld add ${v} ${x}";
    fi;
done;
for v in ${has}; do
    reload='1';
    x=$(${exe} --remove-port=${v}) || f_fail "init: firewalld del ${v}";
    f_info "init: firewalld del ${v} ${x}";
done;
if [[ -n "${reload}" ]]; then
    x=$(firewall-cmd --reload) || f_fail 'init: firewalld reload';
    f_info "init: firewalld reload ${x}";
fi;

######## php多版本源
if [[ -f "${MEM}/php.list" ]]; then f_info 'init: php.source already';
else
    f_wait 'init: php source';
    wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg \
        f_fail 'init: php.source gpg';
    echo 'deb https://packages.sury.org/php/ buster main' \
        > /etc/apt/sources.list.d/php.list || f_fail 'init: php.source list';
    apt-get update || f_fail 'init: php.source update';
    echo >"${MEM}/php.list" || f_fail 'init: php.source status';
fi;

echo > /dev/null;
